package com.power.services.dataDictionary;

import com.power.dao.dataDictionary.TddDataDAO;
import com.power.dao.dataDictionary.TddDefinitionDAO;
import com.power.model.dataDictionary.TddData;
import com.power.model.dataDictionary.TddDefinition;
import com.power.model.dataDictionary.TreeData;
import com.power.model.dataDictionary.TreeDataCHK;
import com.power.util.StringUtil;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service("dataDictionaryService")
public class DataDictionaryServiceImpl implements DataDictionaryService {

	@Autowired
	private TddDataDAO tddDataDAO;

	@Autowired
	private TddDefinitionDAO tddDefinitionDAO;

	public void createData(TddData transientObject) {
		this.tddDataDAO.save(transientObject);
	}

	public void createDefinition(TddDefinition transientObject) {
		this.tddDefinitionDAO.save(transientObject);
	}

	public TddData readData(Integer id) {
		return ((TddData) this.tddDataDAO.load(id));
	}

	public TddDefinition readDefinition(Integer id) {
		return ((TddDefinition) this.tddDefinitionDAO.load(id));
	}

	public void updateData(TddData transientObject) {
		this.tddDataDAO.update(transientObject);
	}

	public void updateDefinition(TddDefinition transientObject) {
		this.tddDefinitionDAO.update(transientObject);
	}

	public void deleteData(TddData persistentObject) {
		this.tddDataDAO.delete(persistentObject);
	}

	public void deleteDefinition(TddDefinition persistentObject) {
		this.tddDataDAO
				.bulkUpdate("delete from  com.power.model.dataDictionary.TddData dd where dd.tddDefinition.ddId="
						+ persistentObject.getDdId());
		this.tddDefinitionDAO.delete(persistentObject);
	}

	public List<TddDefinition> findAllDefinition() {
		return this.tddDefinitionDAO
				.find("select d from com.power.model.dataDictionary.TddDefinition d  order by d.ordernum");
	}

	public List<TddDefinition> findAllDefinitionByddType(String ddType,
			String name, String describe) {
		return this.tddDefinitionDAO
				.find("select d from com.power.model.dataDictionary.TddDefinition d where d.ddType like '"
						+ ddType
						+ "'  and d.name like '"
						+ name
						+ "'"
						+ "  and (ifnull(d.describe,'%')  like '"
						+ describe
						+ "' ) " + "  order by d.nbcode");
	}

	public List<TddDefinition> findDefinitionBy(String code) {
		return this.tddDefinitionDAO
				.find("select d from com.power.model.dataDictionary.TddDefinition d  where d.code='"
						+ code + "'");
	}

	public List<TddData> findAllDataByDDID(Integer ddId) {
		return this.tddDataDAO
				.find("select dd from com.power.model.dataDictionary.TddData dd where dd.tddDefinition.ddId="
						+ ddId + " order by dd.code");
	}

	public List<TddData> findDataByDDIDAndCode(Integer ddId, String code) {
		return this.tddDataDAO
				.find("select dd from com.power.model.dataDictionary.TddData dd where dd.tddDefinition.ddId="
						+ ddId
						+ " and dd.code like '"
						+ StringUtil.getShortCode(code)
						+ "%' "
						+ "and dd.code!='" + code + "'  order by dd.code");
	}

	public List<TddData> findAllDataByCode(String code) {
		return this.tddDataDAO
				.find("select dd from com.power.model.dataDictionary.TddData dd where dd.tddDefinition.code='"
						+ code + "' order by dd.code");
	}

	public List<TddData> findDataByDefAndCode(String def, String code) {
		return this.tddDataDAO
				.find("select dd from com.power.model.dataDictionary.TddData dd where dd.code='"
						+ code
						+ "' and dd.tddDefinition.code='"
						+ def
						+ "' order by dd.code");
	}

	public List<TreeData> buildTreeData(String keyword) {
		List treeList = new ArrayList();
		DetachedCriteria criteria = DetachedCriteria.forClass(TddData.class);
		criteria.createAlias("tddDefinition", "dd").add(
				Restrictions.eq("dd.code", keyword));
		criteria.addOrder(Order.asc("code"));
		List listAll = this.tddDataDAO.findByCriteria(criteria);
		if (listAll.size() > 0) {
			String firstCode = ((TddData) listAll.get(0)).getCode();
			criteria = DetachedCriteria.forClass(TddData.class);
			criteria.createAlias("tddDefinition", "dd").add(
					Restrictions.eq("dd.code", keyword));
			criteria.add(Restrictions.like("code", firstCode.replaceAll(
					StringUtil.getShortCode(firstCode), "__")));
			criteria.addOrder(Order.asc("code"));
			List list1 = this.tddDataDAO.findByCriteria(criteria);
			if (list1.size() > 0) {
				for (int i = 0; i < list1.size(); ++i) {
					TreeData tc = new TreeData();
					tc.setText(((TddData) list1.get(i)).getCode() + "  "
							+ ((TddData) list1.get(i)).getName());
					tc.setCode(((TddData) list1.get(i)).getCode());
					tc.setTextWithoutCode(((TddData) list1.get(i)).getName());
					tc.setDescribe(((TddData) list1.get(i)).getDescribe());
					tc.setId(((TddData) list1.get(i)).getDddId().intValue());
					tc.setChildren(getTreeChildren(listAll, tc.getCode()));
					treeList.add(tc);
				}
			}
		}
		return treeList;
	}

	public List<TreeData> buildTreeDataById(Integer keyword) {
		List treeList = new ArrayList();
		DetachedCriteria criteria = DetachedCriteria.forClass(TddData.class);
		criteria.createAlias("tddDefinition", "dd").add(
				Restrictions.eq("dd.ddId", keyword));
		criteria.addOrder(Order.asc("code"));
		List listAll = this.tddDataDAO.findByCriteria(criteria);
		if (listAll.size() > 0) {
			String firstCode = ((TddData) listAll.get(0)).getCode();
			criteria = DetachedCriteria.forClass(TddData.class);
			criteria.createAlias("tddDefinition", "dd").add(
					Restrictions.eq("dd.ddId", keyword));
			criteria.add(Restrictions.like("code", firstCode.replaceAll(
					StringUtil.getShortCode(firstCode), "__")));
			criteria.addOrder(Order.asc("code"));
			List list1 = this.tddDataDAO.findByCriteria(criteria);
			if (list1.size() > 0) {
				for (int i = 0; i < list1.size(); ++i) {
					TreeData tc = new TreeData();
					tc.setText(((TddData) list1.get(i)).getCode() + "  "
							+ ((TddData) list1.get(i)).getName());
					tc.setCode(((TddData) list1.get(i)).getCode());
					tc.setTextWithoutCode(((TddData) list1.get(i)).getName());
					tc.setDescribe(((TddData) list1.get(i)).getDescribe());
					tc.setId(((TddData) list1.get(i)).getDddId().intValue());
					tc.setChildren(getTreeChildren(listAll, tc.getCode()));
					treeList.add(tc);
				}
			}
		}
		return treeList;
	}

	public List<TreeDataCHK> buildCHKTreeDataById(Integer keyword,
			String[] value) {
		List treeList = new ArrayList();
		DetachedCriteria criteria = DetachedCriteria.forClass(TddData.class);
		criteria.createAlias("tddDefinition", "dd").add(
				Restrictions.eq("dd.ddId", keyword));
		criteria.addOrder(Order.asc("code"));
		List listAll = this.tddDataDAO.findByCriteria(criteria);
		if (listAll.size() > 0) {
			String firstCode = ((TddData) listAll.get(0)).getCode();
			criteria = DetachedCriteria.forClass(TddData.class);
			criteria.createAlias("tddDefinition", "dd").add(
					Restrictions.eq("dd.ddId", keyword));
			criteria.add(Restrictions.like("code", firstCode.replaceAll(
					StringUtil.getShortCode(firstCode), "__")));
			criteria.addOrder(Order.asc("code"));
			List list1 = this.tddDataDAO.findByCriteria(criteria);
			if (list1.size() > 0) {
				for (int i = 0; i < list1.size(); ++i) {
					TreeDataCHK tc = new TreeDataCHK();
					tc.setText(((TddData) list1.get(i)).getCode() + "  "
							+ ((TddData) list1.get(i)).getName());
					tc.setCode(((TddData) list1.get(i)).getCode());
					tc.setTextWithoutCode(((TddData) list1.get(i)).getName());
					tc.setDescribe(((TddData) list1.get(i)).getDescribe());
					tc.setId(((TddData) list1.get(i)).getDddId().intValue());
					tc.setChecked(hasChecked(tc.getCode(), value));
					tc.setChildren(getTreeChildrenCHK(listAll, tc.getCode(),
							value));
					treeList.add(tc);
				}
			}
		}
		return treeList;
	}

	private List<TreeData> getTreeChildren(List<TddData> listAll, String code) {
		List list = findTree(listAll, code);
		List treeList = new ArrayList();
		for (int i = 0; i < list.size(); ++i) {
			TddData c = (TddData) list.get(i);
			TreeData tc = new TreeData();
			tc.setText(c.getCode() + "  " + c.getName());
			tc.setCode(c.getCode());
			tc.setId(c.getDddId().intValue());
			tc.setTextWithoutCode(c.getName());
			tc.setDescribe(c.getDescribe());
			if (StringUtil.getShortCode(tc.getCode()).length() < tc.getCode()
					.length())
				tc.setChildren(getTreeChildren(listAll, tc.getCode()));
			else {
				tc.setChildren(new ArrayList());
			}
			treeList.add(tc);
		}
		return treeList;
	}

	private List<TreeDataCHK> getTreeChildrenCHK(List<TddData> listAll,
			String code, String[] value) {
		List list = findTree(listAll, code);
		List treeList = new ArrayList();
		for (int i = 0; i < list.size(); ++i) {
			TddData c = (TddData) list.get(i);
			TreeDataCHK tc = new TreeDataCHK();
			tc.setText(c.getCode() + "  " + c.getName());
			tc.setCode(c.getCode());
			tc.setId(c.getDddId().intValue());
			tc.setChecked(hasChecked(tc.getCode(), value));
			tc.setTextWithoutCode(c.getName());
			tc.setDescribe(c.getDescribe());
			if (StringUtil.getShortCode(tc.getCode()).length() < tc.getCode()
					.length())
				tc
						.setChildren(getTreeChildrenCHK(listAll, tc.getCode(),
								value));
			else {
				tc.setChildren(new ArrayList());
			}
			treeList.add(tc);
		}
		return treeList;
	}

	private List<TddData> findTree(List<TddData> listAll, String code) {
		List treeList = new ArrayList();
		for (int i = 0; i < listAll.size(); ++i) {
			if ((((TddData) listAll.get(i)).getCode().equals(code))
					|| (!(StringUtil.getParentCode(((TddData) listAll.get(i))
							.getCode()).equals(code))))
				continue;
			treeList.add(listAll.get(i));
		}

		return treeList;
	}

	public boolean hasChecked(String code, String[] value) {
		if ((value != null) && (value.length > 0)) {
			for (int i = 0; i < value.length; ++i) {
				if (code.equals(value[i]))
					return true;
			}
		}
		return false;
	}
}